// xml_test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "../tiny/txml.h"

#include <stdarg.h>
#include <iostream>
#include <fstream>


std::ostream& operator<<(std::ostream& ostr, const TXML::String& str)
{
	if(str.empty())
		return ostr;
	else
		return ostr.write(str.begin(), str.length());
}

class TestConsumer : public TXML::Consumer
{
	void BeginDocument(const TXML::String& name, const TXML::String& ns)
	{
		std::cout << "doc-begin: " << name << std::endl;
	}
	void EndDocument() 
	{
		std::cout << "doc-end" << std::endl;
	}

	//elements, any node that isn't the document or a comment
	void BeginElement(const TXML::String& name, const TXML::String& ns)
	{
		if(ns.empty())
			std::cout << "elem-begin: " << name << std::endl;
		else
			std::cout << "elem-begin: " << ns << "." << name << std::endl;
	}
	void ElementContents(const TXML::String& text)
	{
		std::cout << "\telem-contents: " << text << std::endl;
	}
	void EndElement() 
	{
		std::cout << "elem-end" << std::endl;
	};

	//attributes can appear on any element, including processing instructions
	void Attribute(const TXML::String& name, const TXML::String& ns, const TXML::String& value) 
	{
		if(ns.empty())
			std::cout << "\tattr: " << name << " = " << value << std::endl;
		else
			std::cout << "\tattr: " << ns << "." << name << " = " << value << std::endl;
	};
	
	//namespace declaration, called instead of Attribute for "xmlns:foo=uri" constructs
	void NamespaceDeclaration(const TXML::String& ns, const TXML::String& uri) 
	{
		std::cout << "namespace-decl: " << uri << std::endl;
	};

	//raw cdata block
	void CData(const TXML::String& cdata) 
	{
		std::cout << "CDATA: " << cdata << std::endl;
	}

	//errors:
	void ElementError(const TXML::String& elem) 
	{
		std::cout << "!element-error: " << elem << std::endl;
	}
	void AttributeError(const TXML::String& attr) 
	{
		std::cout << "!attr-error: " << attr << std::endl;
	};
	void ParseError(TXML::EParseErrors error) 
	{
		std::cout << "!parser-error: " << int(error) << std::endl;
	};

};

int _tmain(int argc, _TCHAR* argv[])
{
	if(argc > 1)
	{
		std::ifstream file(argv[1], std::ios_base::binary);
		if(!file.is_open())
			return 2;

		//read as binary, buffer as char - the text handling is all up to the xml parser
		file.seekg(0, std::ios_base::end);
		size_t fileLen = file.tellg();
		file.seekg(0, std::ios_base::beg);
		
		char* buffer = new char[fileLen];
		file.read(buffer, fileLen);
		
		{
			TestConsumer T;
			TXML::Parser P;
			P.Parse(buffer, &T);
		}

		delete[] buffer;

		return 0;
	}
	return 1;
}

